/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.cundong.recyclerview.sample.slice;

import static com.cundong.recyclerview.sample.utils.Constants.LOAD_DATA_EVENT;
import static com.cundong.recyclerview.sample.utils.Constants.NEW_CONTACT_COUNT;
import static com.cundong.recyclerview.sample.utils.Constants.NOTIFY_DATA_UPDATE_EVENT;
import static com.cundong.recyclerview.sample.utils.Constants.SLEEP_TIME;

import com.cundong.recyclerview.EndlessRecyclerOnScrollListener;
import com.cundong.recyclerview.HeaderAndFooterRecyclerViewAdapter;
import com.cundong.recyclerview.RecyclerViewUtils;
import com.cundong.recyclerview.ResourceTable;
import com.cundong.recyclerview.sample.bean.Contact;
import com.cundong.recyclerview.sample.provider.ContactItemProvider;
import com.cundong.recyclerview.sample.utils.LoadingFooter;
import com.cundong.recyclerview.sample.utils.LogUtil;
import com.cundong.recyclerview.sample.utils.RecyclerViewStateUtils;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.components.Component;
import ohos.agp.components.LayoutScatter;
import ohos.agp.components.ListContainer;
import ohos.eventhandler.EventHandler;
import ohos.eventhandler.EventRunner;
import ohos.eventhandler.InnerEvent;

import java.lang.ref.WeakReference;
import java.util.ArrayList;

/**
 * EndlessDirectionalLayoutActivity Class
 */
public class EndlessDirectionalLayoutAbilitySlice extends AbilitySlice {
    private static final int LIST_ITEM_COUNT = 20;

    private static final int TOTAL_COUNTER = 64;

    private static final int REQUEST_COUNT = 10;

    private static final String TAG = EndlessDirectionalLayoutAbilitySlice.class.getSimpleName();

    private ListContainer listContainer;

    private ArrayList<Contact> contactData;

    private int mCurrentCounter = 0;

    private ContactItemProvider contactItemProvider;

    private HeaderAndFooterRecyclerViewAdapter mHeaderAndFooterRecyclerViewAdapter = null;

    private PreviewHandler mHandler = new PreviewHandler(EventRunner.create(), this);

    private EndlessRecyclerOnScrollListener mOnScrollListener = new EndlessRecyclerOnScrollListener() {
        @Override
        public void onLoadNextPage(Component component) {
            super.onLoadNextPage(component);

            if (mCurrentCounter < TOTAL_COUNTER) {
                LoadingFooter.State state = RecyclerViewStateUtils.getFooterViewState(listContainer);
                if (state == LoadingFooter.State.Loading) {
                    LogUtil.info(TAG, "the state is Loading, just wait..");
                    return;
                }
            }

            if (mCurrentCounter < TOTAL_COUNTER) {
                // loading more
                RecyclerViewStateUtils.setFooterViewState(EndlessDirectionalLayoutAbilitySlice.this, listContainer,
                    REQUEST_COUNT, LoadingFooter.State.Loading, null);
                requestData();
            } else {
                if (!mHeaderAndFooterRecyclerViewAdapter.hasReachedEnd()) {
                    // The End
                    RecyclerViewStateUtils.setFooterViewState(EndlessDirectionalLayoutAbilitySlice.this, listContainer,
                        REQUEST_COUNT, LoadingFooter.State.TheEnd, null);
                }
            }
        }
    };

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_list_container_layout);

        Component listContainerComponent = findComponentById(ResourceTable.Id_list_container);
        if (listContainerComponent instanceof ListContainer) {
            listContainer = (ListContainer)listContainerComponent;
        }
        initContactData();
        mCurrentCounter = contactData.size();
        initProvider();

        mHeaderAndFooterRecyclerViewAdapter = new HeaderAndFooterRecyclerViewAdapter(contactItemProvider);
        listContainer.setItemProvider(mHeaderAndFooterRecyclerViewAdapter);

        LayoutScatter mLayoutScatter = LayoutScatter.getInstance(this);
        RecyclerViewUtils.setHeaderView(listContainer,
            mLayoutScatter.parse(ResourceTable.Layout_header_layout, null, false));

        listContainer.setScrolledListener(mOnScrollListener);
    }

    private void initProvider() {
        contactItemProvider = new ContactItemProvider(this, contactData);
    }

    private void initContactData() {
        contactData = new ArrayList<>();
        for (int index = 0; index < LIST_ITEM_COUNT; index++) {
            addContact(index);
        }
    }

    private void addContact(int index) {
        contactData.add(new Contact("User " + index, "100000000" + index));
    }

    @Override
    public void onActive() {
        super.onActive();
    }

    @Override
    public void onForeground(Intent intent) {
        super.onForeground(intent);
    }

    private void requestData() {
        new Thread() {
            @Override
            public void run() {
                super.run();

                try {
                    Thread.sleep(SLEEP_TIME);
                } catch (InterruptedException e) {
                    LogUtil.error(TAG, "InterruptedException occured");
                }
                mHandler.sendEvent(LOAD_DATA_EVENT);
            }
        }.start();
    }

    /**
     * PreviewHandler Class
     */
    private static class PreviewHandler extends EventHandler {
        private WeakReference<EndlessDirectionalLayoutAbilitySlice> ref;

        PreviewHandler(EventRunner runner, EndlessDirectionalLayoutAbilitySlice endlessDirectionalLayoutAbilitySlice)
            throws IllegalArgumentException {
            super(runner);
            ref = new WeakReference<>(endlessDirectionalLayoutAbilitySlice);
        }

        @Override
        public void processEvent(InnerEvent event) {
            final EndlessDirectionalLayoutAbilitySlice abilitySlice = ref.get();
            if (abilitySlice == null) {
                return;
            }

            switch (event.eventId) {
                case LOAD_DATA_EVENT:
                    int currentSize = abilitySlice.contactItemProvider.getCount();
                    ArrayList<Contact> newList = new ArrayList<>();
                    for (int index = 0; index < NEW_CONTACT_COUNT; index++) {
                        if (newList.size() + currentSize >= TOTAL_COUNTER) {
                            break;
                        }
                        int nextIndex = index + currentSize;
                        newList.add(new Contact("User " + nextIndex, "100000000" + nextIndex));
                    }

                    abilitySlice.addItems(newList);
                    RecyclerViewStateUtils.setFooterViewState(abilitySlice.listContainer, LoadingFooter.State.Normal);
                    break;
                case NOTIFY_DATA_UPDATE_EVENT:
                    abilitySlice.notifyDataSetChanged();
                    break;
                default:
                    break;
            }
        }
    }

    private void addItems(ArrayList<Contact> contactList) {
        contactItemProvider.addData(contactList);
        mCurrentCounter += contactList.size();
    }

    private void notifyDataSetChanged() {
        mHeaderAndFooterRecyclerViewAdapter.notifyDataChanged();
    }
}
